/*
 * Class to add Visual Signature Indicators to Documents for Signatures and
 * Stamps.
 */
package us.gaaoc.framework.signature.visual;

import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;

import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;

import us.gaaoc.framework.dao.ModelFacade;
import us.gaaoc.framework.dao.ModelFacadeHibernate;
import us.gaaoc.framework.model.DocumentSigConfig;
import us.gaaoc.framework.model.DocumentStatus;
import us.gaaoc.framework.model.Documents;
import us.gaaoc.framework.model.LdapDirectoryPerson;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.VisualMark;
import us.gaaoc.framework.model.VisualMarkCategory;
import us.gaaoc.framework.signature.digital.DigitalSigner;
import us.gaaoc.framework.signature.digital.ldap.LdapClient;
import us.gaaoc.framework.signature.visual.controllers.SignDateController;
import us.gaaoc.framework.util.DateUtil;
import us.gaaoc.framework.util.pdf.PDFTextTargetsUtility;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.sun.org.apache.bcel.internal.generic.DCONST;

/**
 * Reads the pages of an existing PDF file, adds stamps and visual signature
 * indicators.
 * 
 * @author jih
 * @author mcelratr
 */
public class PDFStamper {
	/**
	 * Reads the pages of an existing PDF file, adds pagenumbers and a
	 * watermark.
	 * 
	 * @param args
	 *            no arguments needed
	 */
	public byte[] readinPDFInByte;

	public byte[] returnedPDFInByte;

	private int stampedSignPage = 0;

	private static transient Logger LOG = Logger.getLogger(PDFStamper.class);

	public PDFStamper() {
	};

	public ModelFacade getModelFacade() {
		return ModelFacadeHibernate.getInstance();
	}

	/**
	 * Method to add a visual signature indicator to a PDF after a digital 
	 * signature has been created
	 * @param doc The document to be modified
	 * @param img The image related to the person who created the digital 
	 * signature
	 * @param personSigned The person who signed the document
	 * @return a byte array of the document after modification
	 */
	public byte[] addVisualSignatureIndicator(Documents doc, Image img,
			Person personSigned) {
		System.out.println("Add visual signature indicator");
		try {

			// Read in the pdf file's content and create a temp file with
			// coresponding title
			String pdfToRead = doc.getTitle() + ".pdf";
			readinPDFInByte = doc.getContent();
			if (readinPDFInByte.length == 0) {
				System.out.println("Can not add visual signature!");
			}
			System.out.println("The pdf file is " + pdfToRead);
			PdfReader reader = new PdfReader(readinPDFInByte);
			//int n = reader.getNumberOfPages();

			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();

			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			// adding some metadata
			HashMap<String, Person> moreInfo = new HashMap<String, Person>();

			moreInfo.put("Author", personSigned);
			stamp.setMoreInfo(moreInfo);

			// adding content to each page
			int i = 0;
			PdfContentByte under;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			/* TODO Remove calls to docSigConfig for page number after modifying
			 * target finder utility to report the page number that they target
			 * was found on.  Replace with call to find out what target to look
			 * for from database instead of the page number.
			 */

			int documentInstanceCode = doc.getDocumentInstance().getCode();
			/*
			 * TODO Determine if docSigConfig is still needed in the same way 
			 * that is used currently.  Determine updates needed or if to 
			 * remove.
			 */

			DocumentSigConfig docSigConfig = this.getModelFacade()
					.getDocumentSigConfig(documentInstanceCode, personSigned);
			// img.setAbsolutePosition(docSigConfig.getCoordinate_X(),
			// docSigConfig.getCoordinate_Y());

			// to find the x and y co-ordinates for the signature image
			float x_coOrdinate = 0, y_coOrdinate = 0;
			char target = '~'; // character to get exact position of signature
			InputStream in = new ByteArrayInputStream(doc.getContent());
			// PDFTextTargetsUtility to get the x and y co-ordinates
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			float sigCoordinates[] = fttcu
					.findTextTargetCoordinates(target, in);

			x_coOrdinate = sigCoordinates[0];
			y_coOrdinate = sigCoordinates[1] + 10;
			//y_coOrdinate = sigCoordinates[1] - 10;

			img.setAbsolutePosition(x_coOrdinate, y_coOrdinate);

			i = docSigConfig.getPageNumber();
			under = stamp.getUnderContent(i);
			under.addImage(img);

			over = stamp.getOverContent(i);
			over.beginText();

			over.setFontAndSize(bf, 16);
			over.setColorFill(new Color(148, 0, 219));

			/*
			 * TODO Need to add a configuration in db for doc's to add date to
			 * and those to not add date to instead of having this hard coded
			 */
			// If "Request for Admissions" document then do not put the date on 
			// the document after signing.
			/* Request for Admission Codes for Washington and Bibb
			 * 105, 109, 119, 126, 132, 159
			 * Notice to Produce Codes for Washington and Bibb
			 * 161, 166, 53, 54
			 */
			if (!(documentInstanceCode == 105)
					&& !(documentInstanceCode == 109)
					&& !(documentInstanceCode == 119)
					&& !(documentInstanceCode == 126)
					&& !(documentInstanceCode == 132)
					&& !(documentInstanceCode == 159)
					&& !(documentInstanceCode == 161)
					&& !(documentInstanceCode == 166)
					&& !(documentInstanceCode == 53)
					&& !(documentInstanceCode == 54)) {
				// variables to find the x and y co-ordinates for the signature date
				float x_date = 0, y_date = 0;

				// char * to specify exact location of signature date
				char dateTarget = '*';
				float dateCoOrdinates[] = fttcu.findTextTargetCoordinates(
						dateTarget, new ByteArrayInputStream(doc.getContent()));
				x_date = dateCoOrdinates[0];
				y_date = dateCoOrdinates[1] - 10;

				GregorianCalendar calendar = new GregorianCalendar();
				// The target was not found, so return an empty byte array.
				if (x_date == 0.0 && y_date == 0.0) {
					return returnedPDFInByte;
				}
				String day = calendar.get(Calendar.DATE) + "";
				String month = (calendar.get(Calendar.MONTH) + 1) + "";
				String year = calendar.get(Calendar.YEAR) + "";

				// Convert month date number to name of month
				month = DateUtil.changeMonthFromNumberToWord(month);
               
				
				over.showTextAligned(Element.ALIGN_LEFT, day, x_date,
						y_date + 10, 0);
				over.showTextAligned(Element.ALIGN_LEFT, month, x_date + 95,
						y_date + 10, 0);
				over.showTextAligned(Element.ALIGN_LEFT, year, x_date + 180,
						y_date + 10, 0);
			}

			over.endText();
			stamp.close();

			returnedPDFInByte = fileBAOS.toByteArray();
		} catch (Exception de) {
			de.printStackTrace();
		}
		return returnedPDFInByte;
	}

	public int getStampedSignPage()
	{
		return stampedSignPage;
	}
	
	/**
	 * Method to add a visual signature indicator to a PDF after a digital 
	 * signature has been created
	 * @param doc The document to be modified
	 * @param img The image related to the person who created the digital 
	 * signature
	 * @param personSigned The person who signed the document
	 * @return a byte array of the document after modification
	 */
	public byte[] addVisualSignatureIndicator(Documents doc, Image img,
			Person personSigned, String targetPassedIn) {
		System.out.println("Add visual signature indicator");
		String target = targetPassedIn;

		try {

			// Read in the pdf file's content and create a temp file with
			// coresponding title
			String pdfToRead = doc.getTitle() + ".pdf";
			readinPDFInByte = doc.getContent();
			if (readinPDFInByte == null) {
				System.out.println("Can not add visual signature!");
				return null;
			}

			System.out.println("The pdf file is " + pdfToRead);
			PdfReader reader = new PdfReader(readinPDFInByte);
			//int n = reader.getNumberOfPages();

			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();

			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			// adding some metadata
			HashMap<String, String> moreInfo = new HashMap<String, String>();
			//author information to put, if any in modified PDF documents
			moreInfo.put("Author", personSigned.getFirstName());
			stamp.setMoreInfo(moreInfo);

			// adding content to each page
			int i = 0;
			PdfContentByte under;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			// to find the x and y co-ordinates for the signature image
			float x_coOrdinate = 0, y_coOrdinate = 0;
			//char target = '~'; // character to get exact position of signature
			InputStream docToStamp = new ByteArrayInputStream(doc.getContent());
			// PDFTextTargetsUtility to get the x and y co-ordinates
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			
			float sigCoordinates[] = new float[2];
			
			if (target.length() != 1) {
				/* 
				 * For signatures, the coordinates need to come from the first
				 * character of the target and line up with the start of the 
				 * target.  This allows signature indicator images to line up
				 * correctly on signature block lines.
				 */
				sigCoordinates = fttcu.findTextTargetCoordinates(target,docToStamp, true, true);
				//sigCoordinates = fttcu.findTextTargetCoordinates(target,docToStamp, false, false);
			} else {
				sigCoordinates = fttcu.findTextTargetCoordinates(target
						.charAt(0), docToStamp);
			}
		
			x_coOrdinate = sigCoordinates[0];
			y_coOrdinate = sigCoordinates[1];
			if (x_coOrdinate == 0.0 && y_coOrdinate == 0.0) {
				// The target was not found, so return an empty byte array.
				return returnedPDFInByte;
			}

			y_coOrdinate += 10;
			//y_coOrdinate = sigCoordinates[1] - 10;

			img.setAbsolutePosition(x_coOrdinate, y_coOrdinate);

			int targetlocations[] = fttcu.getPagesWhereTargetIsFound();
			int arrayLength = targetlocations.length;
			if (arrayLength <= 0) {
				i = 1;
			} else {
				i = targetlocations[0];
			}

			stampedSignPage = i;
			
			under = stamp.getUnderContent(i);
			under.addImage(img);

			over = stamp.getOverContent(i);
			over.beginText();

			over.setFontAndSize(bf, 16);
			over.setColorFill(new Color(148, 0, 219));

			/*
			 * TODO Need to add a configuration in db for doc's to add date to
			 * and those to not add date to instead of having this hard coded
			 */
			// If "Request for Admissions" document then do not put the date on 
			// the document after signing.
			/* Request for Admission Codes for Washington and Bibb
			 * 105, 109, 119, 126, 132, 159
			 * Notice to Produce Codes for Washington and Bibb
			 * 161, 166, 53, 54
			 */

			over.endText();
			stamp.close();

			returnedPDFInByte = fileBAOS.toByteArray();
		} catch (Exception de) {
			de.printStackTrace();
		}
		return returnedPDFInByte;
	}

	/**
	 * Method to add a visual signature indicator to a PDF after a digital 
	 * signature has been created
	 * @param doc The document to be modified
	 * @param img The image related to the person who created the digital 
	 * signature
	 * @param personSigned The person who signed the document
	 * @param xOffset The amount of an x-axis offset to add 
	 * @param yOffset The amount of a y-axis offset to add
	 * @return a byte array of the document after modification
	 */
	public byte[] addVisualSignatureIndicator(Documents doc, Image img,
			Person personSigned, String targetPassedIn, int xOffset, int yOffset) {
		System.out.println("Add visual signature indicator");
		String target = targetPassedIn;
		try {

			// Read in the pdf file's content and create a temp file with
			// coresponding title
			String pdfToRead = doc.getTitle() + ".pdf";
			readinPDFInByte = doc.getContent();

			System.out.println("The pdf file is " + pdfToRead);
			PdfReader reader = new PdfReader(readinPDFInByte);
			//int n = reader.getNumberOfPages();

			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();

			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			// adding some metadata
			HashMap<String, Person> moreInfo = new HashMap<String, Person>();
			//author information to put, if any in modified PDF documents
			moreInfo.put("Author", personSigned);
			stamp.setMoreInfo(moreInfo);
			// adding content to each page
			int i = 0;
			PdfContentByte under;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			/* TODO Remove calls to docSigConfig for page number after modifying
			 * target finder utility to report the page number that they target
			 * was found on.  Replace with call to find out what target to look
			 * for from database instead of the page number.
			 */
			//int documentCategoryCode = doc.getDocumentInstance()
			//	.getDocumentType().getDocumentCategory().getCode();
			int documentInstanceCode = doc.getDocumentInstance().getCode();
			/*
			 * TODO Determine if docSigConfig is still needed in the same way 
			 * that is used currently.  Determine updates needed or if to 
			 * remove.
			 */

			DocumentSigConfig docSigConfig = this.getModelFacade()
					.getDocumentSigConfig(documentInstanceCode, personSigned);
			// img.setAbsolutePosition(docSigConfig.getCoordinate_X(),
			// docSigConfig.getCoordinate_Y());

			// to find the x and y co-ordinates for the signature image
			float x_coOrdinate = 0, y_coOrdinate = 0;
			//char target = '~'; // character to get exact position of signature
			InputStream docToStamp = new ByteArrayInputStream(doc.getContent());
			// PDFTextTargetsUtility to get the x and y co-ordinates
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			float sigCoordinates[] = fttcu.findTextTargetCoordinates(target,
					docToStamp, true, true);

			x_coOrdinate = sigCoordinates[0];
			y_coOrdinate = sigCoordinates[1];
			if (x_coOrdinate == 0.0 && y_coOrdinate == 0.0) {
				// The target was not found, so return an empty byte array.
				return returnedPDFInByte;
			}
			x_coOrdinate += xOffset;
			y_coOrdinate += yOffset;
			//y_coOrdinate = sigCoordinates[1] - 10;

			img.setAbsolutePosition(x_coOrdinate, y_coOrdinate);

			if (docSigConfig != null) {
				i = docSigConfig.getPageNumber();
			} else {
				int targetlocations[] = fttcu.getPagesWhereTargetIsFound();
				int arrayLength = targetlocations.length;
				if (arrayLength <= 0) {
					i = 1;
				} else {
					i = targetlocations[0];
				}

			}

			stampedSignPage = i;
			
			under = stamp.getUnderContent(i);
			under.addImage(img);

			over = stamp.getOverContent(i);
			over.beginText();

			over.setFontAndSize(bf, 16);
			over.setColorFill(new Color(148, 0, 219));

			/*
			 * TODO Need to add a configuration in db for doc's to add date to
			 * and those to not add date to instead of having this hard coded
			 */
			// If "Request for Admissions" document then do not put the date on 
			// the document after signing.
			/* Request for Admission Codes for Washington and Bibb
			 * 105, 109, 119, 126, 132, 159
			 * Notice to Produce Codes for Washington and Bibb
			 * 161, 166, 53, 54
			 */
			if (!(documentInstanceCode == 105)
					&& !(documentInstanceCode == 109)
					&& !(documentInstanceCode == 119)
					&& !(documentInstanceCode == 126)
					&& !(documentInstanceCode == 132)
					&& !(documentInstanceCode == 159)
					&& !(documentInstanceCode == 161)
					&& !(documentInstanceCode == 166)
					&& !(documentInstanceCode == 53)
					&& !(documentInstanceCode == 54)) {
				// variables to find the x and y co-ordinates for the signature date
				float x_date = 0, y_date = 0;

				// char * to specify exact location of signature date
				char dateTarget = '*';
				ByteArrayInputStream bais = new ByteArrayInputStream(doc
						.getContent());
				float dateCoOrdinates[] = fttcu.findTextTargetCoordinates(
						dateTarget, bais);
				x_date = dateCoOrdinates[0];
				y_date = dateCoOrdinates[1];

				// TODO Replace this sign date stamp with a more permanent 
				// solution for orders
				if (x_date == 0.0 && y_date == 0.0) {
					String dateTargetString = "So Ordered, this";
					bais = new ByteArrayInputStream(doc.getContent());
					dateCoOrdinates = fttcu.findTextTargetCoordinates(
							dateTargetString, bais, true, true);
					x_date = dateCoOrdinates[0];
					y_date = dateCoOrdinates[1];
				}
				// If a signing date target was found, then stamp the date.
				if (x_date != 0.0 && y_date != 0.0) {
					//y_date -= 10;
					/*
					TimeZone tz = TimeZone.getTimeZone("America/New_York");
					GregorianCalendar calendar = new GregorianCalendar(tz);
					
					String day = calendar.get(Calendar.DATE) + "";
					String month = (calendar.get(Calendar.MONTH) + 1) + "";
					String year = calendar.get(Calendar.YEAR) + "";
					 */
					String day = new DateUtil().getAocDayOfMonth() + "";
					String month = new DateUtil().getAocMonth() + "";
					String year = new DateUtil().getAocYear() + "";
					// Convert month date number to name of month
					month = DateUtil.changeMonthFromNumberToWord(month);
					/*
					over.showTextAligned(Element.ALIGN_LEFT, day, x_date, y_date + 10, 0);
					over.showTextAligned(Element.ALIGN_LEFT, month, x_date + 95,
							y_date + 10, 0);
					over.showTextAligned(Element.ALIGN_LEFT, year, x_date + 180,
							y_date + 10, 0);
					 */
					over.showTextAligned(Element.ALIGN_LEFT, day, x_date,
							y_date, 0);
					over.showTextAligned(Element.ALIGN_LEFT, month,
							x_date + 95, y_date, 0);
					over.showTextAligned(Element.ALIGN_LEFT, year,
							x_date + 180, y_date, 0);
				} else {
					return returnedPDFInByte;
				}
			}

			over.endText();
			stamp.close();

			returnedPDFInByte = fileBAOS.toByteArray();
		} catch (Exception de) {
			de.printStackTrace();
		}
		return returnedPDFInByte;
	}

	/*
	 * Add Court Stamp on the first page of each PDF file
	 */
	public byte[] AddCourtStamp(Documents docPassed, Image imgPassed,
			Date datePassed, String courtFiledIntoUuidPassed, String stampTarget) {

		System.out.println("Add Court Stamp " + docPassed.getTitle());
		try {
			// Read in the pdf file's content and create a temp file with
			// coresponding title
			String pdfToRead = docPassed.getTitle() + ".pdf";
			readinPDFInByte = docPassed.getContent();

			// TODO Replace Write to disk with passing in of Byte Array from
			// in memory object

			System.out.println("The pdf file is " + pdfToRead);
			PdfReader reader = new PdfReader(readinPDFInByte);
			//int n = reader.getNumberOfPages();

			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// we create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);
			// adding some metadata
			HashMap<String, String> moreInfo = new HashMap<String, String>();
			moreInfo.put("Author", "Clerk of Court");
			stamp.setMoreInfo(moreInfo);

			PdfContentByte under;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			// variables to find the x and y co-ordinates for the court stamp
			float x_stamp = 0, y_stamp = 0;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(docPassed
					.getContent());
			float stampCoOrdinates[] = new float[2];
			if (stampTarget.length() != 1) {
				stampCoOrdinates = fttcu.findTextTargetCoordinates(stampTarget,
						bais, false, false);
			} else {
				stampCoOrdinates = fttcu.findTextTargetCoordinates(stampTarget
						.charAt(0), bais);
			}

			x_stamp = stampCoOrdinates[0];
			y_stamp = stampCoOrdinates[1];

			if (x_stamp > 0.0 && y_stamp > 0.0) {
				y_stamp += 30;
				//	Place the image/stamp on the page
				imgPassed.setAbsolutePosition(x_stamp - 50, y_stamp - 100);
			} else {
				// TODO Need to test and refine the offsets for this.
				// If target not found, then use general default values
				LOG.debug("No target found, using default placement values "
						+ "for court received stamp.");
				// Get the page size
				Rectangle pdfRectangle = reader.getPageSizeWithRotation(1);
				/*
				 * Note:  Pages start with 0,0 at the bottom left hand corner
				 * using the Lowagie iText API for PDF's.
				 */
				// Determine the width of the page.
				float farRightXofPDFPage = pdfRectangle.right();
				// Determine the height of the page.
				float upperYofPDFPage = pdfRectangle.top();
				// Set off sets for each to determine a generic location for the
				// stamp.
				float offSetX = (float) (4.0 / 5.0);
				float offSetY = (float) (7.0 / 8.0);
				farRightXofPDFPage = farRightXofPDFPage * offSetX;
				upperYofPDFPage = upperYofPDFPage * offSetY;
				x_stamp = farRightXofPDFPage;
				y_stamp = upperYofPDFPage;
				// Decrement the positioning for the signature indicator image
				// to be placed below the Court Received Stamp.
				/*	11.14.2008			farRightXofPDFPage -= 50;
				 * 				        upperYofPDFPage -= 100;*/
				farRightXofPDFPage -= 90;
				upperYofPDFPage -= 80;
				LOG.debug("The default x,y used is: " + farRightXofPDFPage
						+ ", " + upperYofPDFPage);
				//img.setAbsolutePosition(350, 580);
				imgPassed.setAbsolutePosition(farRightXofPDFPage,
						upperYofPDFPage);

			}

			// Signature Indicator Image placed under the first page
			under = stamp.getUnderContent(1);
			under.addImage(imgPassed); // Add the image to the page.
	
			// text over the existing page
			over = stamp.getOverContent(1);
			//over.addImage(imgPassed); // Add the image to the page.
		
			over.beginText();
			over.setFontAndSize(bf, 10);
			over.setColorFill(new Color(148, 0, 219));

			Date date = datePassed;
			String signingDate = date.toString().trim();

			// Added by Frank for ticket GAJETWOX-18
			GregorianCalendar calendar = new GregorianCalendar();

			calendar.setTime(date);

			String day = String.valueOf(calendar.get(Calendar.DATE));
			String month = String.valueOf(calendar.get(Calendar.MONTH) + 1);
			String year = String.valueOf(calendar.get(Calendar.YEAR));

			// Convert month date number to name of month
			month = DateUtil.changeMonthFromNumberToWord(month);

			signingDate = month + "-" + day + "-" + year;

			// File Received Stamp

			if(!courtFiledIntoUuidPassed.equalsIgnoreCase("courtUuid5") &&
					!courtFiledIntoUuidPassed.equalsIgnoreCase("courtUuid4"))
			{
		
				
				over.showTextAligned(Element.ALIGN_LEFT, "FILED", 
						x_stamp - 5,y_stamp, 0);
				over.showTextAligned(Element.ALIGN_LEFT, "CLERK'S OFFICE",
						x_stamp - 30, y_stamp - 10, 0);
				over.showTextAligned(Element.ALIGN_LEFT, signingDate, 
						x_stamp - 30,y_stamp - 20, 0);
				over.showTextAligned(Element.ALIGN_LEFT, "SUPERIOR COURT OF ",
						x_stamp - 40, y_stamp - 30, 0);


				CourtStampInformation inf = new CourtStampInformation();
				inf.populate(courtFiledIntoUuidPassed, x_stamp, y_stamp);
				over.showTextAligned(Element.ALIGN_LEFT,
						inf.getCourtStampText(),
						inf.getX_position(),
						inf.getY_position(),
						0);
			} else if (courtFiledIntoUuidPassed.equalsIgnoreCase("courtUuid4")){ //Fulton County
				/*over.showTextAligned(Element.ALIGN_LEFT, signingDate, 
						x_stamp - 30,y_stamp - 20, 0); */
				over.showTextAligned(Element.ALIGN_LEFT, signingDate, 
						x_stamp - 45,y_stamp - 30, 0);
			}
			else{
/*	11.14.2008			over.showTextAligned(Element.ALIGN_LEFT, "FILED", x_stamp - 5,
						y_stamp, 0);
				over.showTextAligned(Element.ALIGN_LEFT, signingDate, 
						x_stamp - 30, y_stamp - 10, 0);*/
				over.showTextAligned(Element.ALIGN_LEFT, "FILED", x_stamp - 5,
						y_stamp - 70, 0);
				over.showTextAligned(Element.ALIGN_LEFT, signingDate, 
						x_stamp - 30, y_stamp - 80, 0);
				

			}
			
			
			over.endText();

			// closing PdfStamper will generate the new PDF file
			stamp.close();

			returnedPDFInByte = fileBAOS.toByteArray();
		} catch (Exception de) {
			de.printStackTrace();
		}
		return returnedPDFInByte;
	}

	
	public byte[] addVisualDocketID(Documents doc,String docketID) {
		System.out.println("Add Docket Id on  " + doc.getTitle());
		try {
			// Read in the PDF file's content and create a temporary file with corresponding title
			String pdfToRead = doc.getTitle() + ".pdf";
			readinPDFInByte = doc.getContent();

			// TODO Replace Write to disk with passing in of Byte Array from
			// in memory object

			System.out.println("The pdf file is " + pdfToRead);
			PdfReader reader = new PdfReader(readinPDFInByte);

			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// we create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);
			
			//PdfContentByte under;
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			///float caseNumberCoOrdinates[] = new float[2];
			// variables to find the x and y co-ordinates for civil case number
			float x_caseNumber = 0, y_caseNumber = 0;
			
			//PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc.getContent());
			
			//We are going to stamp this in a static location.
			/*
			if (caseNumberTarget.length() != 1) {
				caseNumberCoOrdinates = fttcu.findTextTargetCoordinates(caseNumberTarget,bais, false, false);
			} else {
				caseNumberCoOrdinates = fttcu.findTextTargetCoordinates(caseNumberTarget.charAt(0), bais);
			}
			*/
			
			
			//x_caseNumber = caseNumberCoOrdinates[0];
			//y_caseNumber = caseNumberCoOrdinates[1];
			x_caseNumber = CourtStampInformation.getCVPosition_X(doc.getCaseRecord().getCourtUuid(), reader.getPageSize(1).width());
			y_caseNumber = CourtStampInformation.getCVPosition_Y(doc.getCaseRecord().getCourtUuid(), reader.getPageSize(1).height());
			System.out.println("x = "+x_caseNumber +" And y = "+y_caseNumber);
			if(x_caseNumber !=0 && y_caseNumber != 0) {
				// text over the existing page
				over = stamp.getOverContent(1);
				over.beginText();
				over.setFontAndSize(bf, 15);
				over.setColorFill(new Color(148, 0, 219));
				// Civil Action File Number Stamp (aka Docket ID, Court Case Number)
				//over.showTextAligned(Element.ALIGN_LEFT, "CV:"+docketID,x_caseNumber /* + 15 */, y_caseNumber, 0);
				over.showTextAligned(Element.ALIGN_LEFT, docketID, x_caseNumber /* + 15 */, y_caseNumber, 0);
				//y_caseNumber - 10, 0);
				over.endText();
				//	closing PdfStamper will generate the new PDF file
				stamp.close();
	
				returnedPDFInByte = fileBAOS.toByteArray();
				// Clean up Byte Arrays used
				fileBAOS.close();
			 
			}else {
				returnedPDFInByte = null;
			}
		}
		catch (Exception de) {
			de.printStackTrace();
		}

		
		return returnedPDFInByte;
	}

	/**
	 * Method to add a date to a PDF document using a variable target character.
	 * @param doc The document to be stamped.
	 * @param targetPassedIn  The character to search for in the document.
	 * @return A byte array representation of the document.
	 */
	public byte[] addDate(Documents docPassedIn, Date datePassedIn,
			String targetPassedIn) {
		try {
			/*
			 * TODO Need to modularize the stamping code into sections to keep from
			 * repeating the same steps with each of the stampin methods.
			 */
			/*
			 * TODO Need to add more flexiblity for this method to allow for using
			 * different pages and different occurences of the target.
			 */

			readinPDFInByte = docPassedIn.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);

			// Create file output stream for modified PDF
			// FileOutputStream fileOS = new FileOutputStream(pdfModified);
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);
			PdfContentByte over;
			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			// variables to find the x and y co-ordinates for civil case number
			float x_date = 0, y_date = 0;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream docToSignBytes = new ByteArrayInputStream(
					docPassedIn.getContent());
			float dateCoOrdinates[] = fttcu.findTextTargetCoordinates(
					targetPassedIn, docToSignBytes, false, true);
			x_date = dateCoOrdinates[0];
			//y_date = dateCoOrdinates[1]-10;
			y_date = dateCoOrdinates[1];
            
            if (x_date == 0.0 && y_date == 0.0) { 
                LOG.debug("No date target found for applying stamp"); 
                // Return original document 
                return readinPDFInByte; 
            } 
			int pagesWhereTargetFound[] = fttcu.getPagesWhereTargetIsFound();
			// Since getting first instance, find the first page where the 
			// target was found.
			over = stamp.getOverContent(pagesWhereTargetFound[0]);
			over.beginText();

			over.setFontAndSize(bf, 12);

			String day;
			String month;
			String year;
			// If no date passed in, use current date
			if (datePassedIn == null) {
				day = new DateUtil().getAocDayOfMonth() + "";
				month = new DateUtil().getAocMonth() + "";
				year = new DateUtil().getAocYear() + "";
			} else {
				DateUtil dateUtil = new DateUtil(datePassedIn);
				day = dateUtil.getAocDayOfMonth() + "";
				month = dateUtil.getAocMonth() + "";
				year = dateUtil.getAocYear() + "";
			}
			// Convert month date number to name of month
			month = DateUtil.changeMonthFromNumberToWord(month);
			
			
			over.showTextAligned(Element.ALIGN_LEFT, day, x_date, y_date, 0);
			over.showTextAligned(Element.ALIGN_LEFT, month, x_date + 100,
					y_date, 0);
			over.showTextAligned(Element.ALIGN_LEFT, year, x_date + 165,
					y_date, 0);
			over.endText();
			//	closing PdfStamper will generate the new PDF file
			stamp.close();

			returnedPDFInByte = fileBAOS.toByteArray();
			// Clean up Byte Arrays used
			fileBAOS.close();
		} catch (Exception de) {
			de.printStackTrace();
		}
		return returnedPDFInByte;
	}

	public byte[] addSignDate(Documents docPassedIn, VisualMark visualMark_signDate, String targetPassedIn,String roleUuid) {
		try {
			Documents doc = docPassedIn;
			readinPDFInByte = doc.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);
			// Create file output stream for modified PDF
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			float x_date = 0, y_date = 0;

			String dateTarget = targetPassedIn;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc
					.getContent());
			float dateCoOrdinates[] = new float[2];
			if (dateTarget.length() != 1) {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget,
						bais, false, false);
			} else {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget
						.charAt(0), bais);
			}
			x_date = dateCoOrdinates[0];
			y_date = dateCoOrdinates[1];

			// If a signing date target was found, then stamp the date.
			if (x_date != 0.0 && y_date != 0.0) {

				PdfContentByte over;
				int pagesWhereTargetFound[] = fttcu
						.getPagesWhereTargetIsFound();
				// Since getting first instance, find the first page where the 
				// target was found.
				
				over = stamp.getOverContent(pagesWhereTargetFound[0]);
				over.setFontAndSize(bf, 12);							
				(new SignDateController()).addSignDate(over,visualMark_signDate,docPassedIn,roleUuid,x_date,y_date);				
				stamp.close();
				returnedPDFInByte = fileBAOS.toByteArray();
			} else {
				returnedPDFInByte = null;
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (DocumentException de) {
			de.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return returnedPDFInByte;

	}
	

	public byte[] addCourtMonth(Documents docPassedIn, String targetPassedIn, String roleUuid, Date courtDate) {
		try {
			Documents doc = docPassedIn;
			readinPDFInByte = doc.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);
			// Create file output stream for modified PDF
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			float x_date = 0, y_date = 0;

			String dateTarget = targetPassedIn;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc
					.getContent());
			float dateCoOrdinates[] = new float[2];
			if (dateTarget.length() != 1) {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget,
						bais, false, false);
			} else {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget
						.charAt(0), bais);
			}
			x_date = dateCoOrdinates[0];
			y_date = dateCoOrdinates[1];

			// If a signing date target was found, then stamp the date.
			if (x_date != 0.0 && y_date != 0.0) {

				PdfContentByte over;
				int pagesWhereTargetFound[] = fttcu
						.getPagesWhereTargetIsFound();
				// Since getting first instance, find the first page where the 
				// target was found.
				over = stamp.getOverContent(pagesWhereTargetFound[0]);
				over.beginText();

				over.setFontAndSize(bf, 9);

				String courtUuid = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("courtUuid");
				
				//TODO: use COURT DATE and not SIGN DATE
				
				y_date -= 10;
				TimeZone tz = TimeZone.getTimeZone("America/New_York");
				
				DateFormat fmt = DateFormat.getDateInstance();

				GregorianCalendar calendar = new GregorianCalendar();
				calendar.setTime(courtDate);
				
				
				
				String day = calendar.get(Calendar.DATE) + "";
				String month = (calendar.get(Calendar.MONTH) + 1) + "";
				String year = calendar.get(Calendar.YEAR) + "";

				// Convert month date number to name of month
				month = DateUtil.changeMonthFromNumberToWord(month);
                //Edited by Bhawana
				
				over.showTextAligned(Element.ALIGN_LEFT, month, x_date,
						y_date + 10, 0);
				
				over.endText();
				stamp.close();
				returnedPDFInByte = fileBAOS.toByteArray();
			} else {
				returnedPDFInByte = null;
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (DocumentException de) {
			de.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return returnedPDFInByte;

	}
	
	public byte[] addCourtDay(Documents docPassedIn, String targetPassedIn, String roleUuid, Date courtDate) {
		try {
			Documents doc = docPassedIn;
			readinPDFInByte = doc.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);
			// Create file output stream for modified PDF
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			float x_date = 0, y_date = 0;

			String dateTarget = targetPassedIn;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc
					.getContent());
			float dateCoOrdinates[] = new float[2];
			if (dateTarget.length() != 1) {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget,
						bais, false, false);
			} else {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget
						.charAt(0), bais);
			}
			x_date = dateCoOrdinates[0];
			y_date = dateCoOrdinates[1];

			// If a signing date target was found, then stamp the date.
			if (x_date != 0.0 && y_date != 0.0) {

				PdfContentByte over;
				int pagesWhereTargetFound[] = fttcu
						.getPagesWhereTargetIsFound();
				// Since getting first instance, find the first page where the 
				// target was found.
				over = stamp.getOverContent(pagesWhereTargetFound[0]);
				over.beginText();

				over.setFontAndSize(bf,12);

				String courtUuid = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("courtUuid");
				
				//TODO: use COURT DATE and not SIGN DATE
				
				y_date -= 10;
				TimeZone tz = TimeZone.getTimeZone("America/New_York");
				
				DateFormat fmt = DateFormat.getDateInstance();

				GregorianCalendar calendar = new GregorianCalendar();
				calendar.setTime(courtDate);
				
				
				
				String day = calendar.get(Calendar.DATE) + "";
				//String month = (calendar.get(Calendar.MONTH) + 1) + "";
				//String year = calendar.get(Calendar.YEAR) + "";

				// Convert month date number to name of month
				//month = DateUtil.changeMonthFromNumberToWord(month);
                //Edited by Bhawana
				over.showTextAligned(Element.ALIGN_LEFT, day, x_date,
						y_date + 10, 0);
				
				if(courtUuid.equalsIgnoreCase("courtUuid3"))
				{
					/*
					 * 	This causes bugs
					if (docPassedIn.getDocumentInstance().getCode() == 196)
					{
						over.showTextAligned(Element.ALIGN_LEFT, month, x_date,
								y_date, 0);
					}else{
						over.showTextAligned(Element.ALIGN_LEFT, month, x_date + 56,
								y_date - 10, 0);
					}
					*/
				}else{
					//over.showTextAligned(Element.ALIGN_LEFT, month, x_date + 100,
						//	y_date + 10, 0);
				}
				
				if(!courtUuid.equalsIgnoreCase("courtUuid3"))
				{
				//	over.showTextAligned(Element.ALIGN_LEFT, year, x_date + 175,
					//		y_date + 10, 0);
				}else{
					//over.showTextAligned(Element.ALIGN_LEFT, year, x_date + 175,
						//	y_date + 10, 0);
				}
				over.endText();
				stamp.close();
				returnedPDFInByte = fileBAOS.toByteArray();
			} else {
				returnedPDFInByte = null;
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (DocumentException de) {
			de.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return returnedPDFInByte;

	}
	
	public byte[] addCourtRoom(Documents docPassedIn, String targetPassedIn, String roleUuid, String courtRoomNumber) {
		try {
			Documents doc = docPassedIn;
			readinPDFInByte = doc.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);
			// Create file output stream for modified PDF
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			float x_date = 0, y_date = 0;

			String dateTarget = targetPassedIn;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc
					.getContent());
			float dateCoOrdinates[] = new float[2];
			if (dateTarget.length() != 1) {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget,
						bais, false, false);
			} else {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget
						.charAt(0), bais);
			}
			x_date = dateCoOrdinates[0];
			y_date = dateCoOrdinates[1];

			// If a signing date target was found, then stamp the date.
			if (x_date != 0.0 && y_date != 0.0) {

				PdfContentByte over;
				int pagesWhereTargetFound[] = fttcu
						.getPagesWhereTargetIsFound();
				// Since getting first instance, find the first page where the 
				// target was found.
				over = stamp.getOverContent(pagesWhereTargetFound[0]);
				over.beginText();

				over.setFontAndSize(bf, 12);

				String courtUuid = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("courtUuid");
				
				y_date -= 10;
				
				String roomNumber = courtRoomNumber;
				
				over.showTextAligned(Element.ALIGN_LEFT, roomNumber, x_date+7	, y_date+10, 0);
				
				over.endText();
				stamp.close();
				returnedPDFInByte = fileBAOS.toByteArray();
			} else {
				returnedPDFInByte = null;
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (DocumentException de) {
			de.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return returnedPDFInByte;
	}
	
	public byte[] addCourtTime(Documents docPassedIn, String targetPassedIn, String roleUuid, String courtTime) {
		try {
			Documents doc = docPassedIn;
			readinPDFInByte = doc.getContent();
			PdfReader reader = new PdfReader(readinPDFInByte);
			// Create file output stream for modified PDF
			ByteArrayOutputStream fileBAOS = new ByteArrayOutputStream();
			// We create a stamper that will copy the document to a new file
			PdfStamper stamp = new PdfStamper(reader, fileBAOS);

			BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
					BaseFont.WINANSI, BaseFont.EMBEDDED);

			float x_date = 0, y_date = 0;

			String dateTarget = targetPassedIn;
			PDFTextTargetsUtility fttcu = new PDFTextTargetsUtility();
			ByteArrayInputStream bais = new ByteArrayInputStream(doc
					.getContent());
			float dateCoOrdinates[] = new float[2];
			if (dateTarget.length() != 1) {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget,
						bais, false, false);
			} else {
				dateCoOrdinates = fttcu.findTextTargetCoordinates(dateTarget
						.charAt(0), bais);
			}
			x_date = dateCoOrdinates[0];
			y_date = dateCoOrdinates[1];

			// If a signing date target was found, then stamp the date.
			if (x_date != 0.0 && y_date != 0.0) {

				PdfContentByte over;
				int pagesWhereTargetFound[] = fttcu
						.getPagesWhereTargetIsFound();
				// Since getting first instance, find the first page where the 
				// target was found.
				over = stamp.getOverContent(pagesWhereTargetFound[0]);
				over.beginText();

				over.setFontAndSize(bf, 9);

				y_date -= 10;
				
				over.showTextAligned(Element.ALIGN_LEFT, courtTime, x_date		, y_date+10, 0);
				
				over.endText();
				stamp.close();
				returnedPDFInByte = fileBAOS.toByteArray();
			} else {
				returnedPDFInByte = null;
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (DocumentException de) {
			de.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return returnedPDFInByte;
	}	
}